package gui.graph.controller;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Paint;
import java.util.Iterator;

import lombok.Data;
import negotiator.Negotiator;

import org.apache.commons.collections15.Transformer;

import producer.impl.Producer;
import product.enums.Category;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.MouseListenerTranslator;
import gui.producer.manager.ProducerManager;

@Data
/**
 * Klasa odpowiedzialna za kontrole nad grafem
 * @author przemek
 *
 */
public class GraphController {
	private Frame frame;
	private DirectedGraph<Producer, MyLink> graph = new DirectedSparseMultigraph<Producer, MyLink>();
	private ProducerManager producerManager;
	private Transformer<Producer, Paint> vertexColor;
	private VisualizationViewer<Producer, MyLink> vv;
	private Negotiator negotiator;
	/**
	 * Dodaje krawedzie do grafu
	 */
	private void addEdge() {
		for (Producer p : producerManager.getAllProducer()) {
			if (p.getCategory().equals(Category.PublishingHouse)) {
				for (Producer p1 : producerManager.getAllProducer()) {
					if (p1.getCategory().equals(Category.PrintingHouse)) {
						graph.addEdge(new MyLink(p, p1), p, p1);
					}
				}
			}
			if (p.getCategory().equals(Category.PrintingHouse)) {
				for (Producer p1 : producerManager.getAllProducer()) {
					if (p1.getCategory().equals(Category.Sawmill)) {
						graph.addEdge(new MyLink(p,p1), p, p1);
					}
				}
			}
		}
	}

	public void init(GraphListener listener) {
		addEdge();
		paintVertex();
		setLayout(listener);
		initNegotiator();

	}
	
	public void initNegotiator(){
		negotiator.setFrame(frame);
		negotiator.setProducers(producerManager.getAllProducer());
		negotiator.start();
	}
	
	
	/**
	 * Metoda ustawiajaco layout dla gui
	 * @param listener
	 */
	private void setLayout(GraphListener listener) {
		Layout<Producer, MyLink> layout = new CircleLayout<Producer, MyLink>(getGraph());
		layout.setSize(new Dimension(500,400));	
		vv = new VisualizationViewer<Producer, MyLink>(layout);	
		vv.setBackground(new Color(159,182,205));
		vv.addMouseListener(new MouseListenerTranslator<Producer,MyLink>(listener, vv));
		vv.getRenderContext().setVertexFillPaintTransformer(vertexColor);
		vv.getRenderContext().setEdgeFillPaintTransformer(edgePaint);
		vv.setPreferredSize(new Dimension(500,400));		
	}
	
		private Transformer<MyLink, Paint> edgePaint = new Transformer<MyLink, Paint>() {
			private final Color[] palette = {new Color(124,252,0), Color.ORANGE}; 
		    public Paint transform(MyLink s) {
		        if(s.getProducer().getCategory().equals(Category.PrintingHouse)){
		        	return palette[0];
		        }
		        else{
		        	return palette[1];
		        }
		    }
		};
	
	/**
	 * Metoda dodajace wierzcholki do grafu
	 */
	public void paintVertex() {
		vertexColor = new Transformer<Producer, Paint>() {
			public Paint transform(Producer i) {
				if (i.getCategory().equals(Category.PublishingHouse))
					return Color.RED;
				else if (i.getCategory().equals(Category.PrintingHouse))
					return Color.BLUE;
				else
					return Color.YELLOW;
			}
		};
	}

}

